import { formatStr } from '../utils/string'
import { E_LOG_LEVEL, ILogParam, ILogService } from '../../typing/service/ILogService'

export class LogService implements ILogService {
  constructor(private readonly configLogLevel: E_LOG_LEVEL) {}

  debug(param: ILogParam): void {
    this.printLog(E_LOG_LEVEL.DEBUG, param)
  }
  info(param: ILogParam): void {
    this.printLog(E_LOG_LEVEL.INFO, param)
  }
  warn(param: ILogParam): void {
    this.printLog(E_LOG_LEVEL.WARN, param)
  }
  error(param: ILogParam): void {
    this.printLog(E_LOG_LEVEL.ERROR, param)
  }

  private printLog(logLevel: E_LOG_LEVEL, param: ILogParam) {
    if (logLevel < this.configLogLevel) {
      return
    }
    const { module, method, message, data } = param
    const log = `[ ${module} ][ ${method} ] ${message}`
    const consoleLog = `[${this.getTimeStr()}]${log}`

    switch (logLevel) {
      case E_LOG_LEVEL.ALL:
      case E_LOG_LEVEL.DEBUG:
        if (data !== undefined && data != null) {
          console.log(consoleLog, data)
        } else {
          console.log(consoleLog)
        }
        break
      case E_LOG_LEVEL.INFO:
        if (data !== undefined && data != null) {
          console.info(consoleLog, data)
        } else {
          console.info(consoleLog)
        }

        break
      case E_LOG_LEVEL.WARN:
        if (data !== undefined && data != null) {
          console.warn(consoleLog, data)
        } else {
          console.warn(consoleLog)
        }
        break
      case E_LOG_LEVEL.ERROR:
        if (data !== undefined && data != null) {
          console.error(consoleLog, data)
        } else {
          console.error(consoleLog)
        }
        break
      case E_LOG_LEVEL.OFF:
        break
      default:
    }
  }

  private getTimeStr(): string {
    const format = '{1}/{2}/{3} {4}:{5}:{6}'
    const date = new Date()
    const year = date.getFullYear()
    const month = date.getMonth() + 1
    const day = date.getDate()
    const hour = date.getHours()
    const minute = date.getMinutes()
    const second = date.getSeconds()

    return formatStr(format, [
      year,
      `${month}`.padStart(2, '0'),
      `${day}`.padStart(2, '0'),
      `${hour}`.padStart(2, '0'),
      `${minute}`.padStart(2, '0'),
      `${second}`.padStart(2, '0')
    ])
  }
}
